package com.lyf.scm.admin.domain.util;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.lyf.scm.admin.api.dto.SalesPlanDirectlyDTO;
import com.lyf.scm.admin.domain.excel.dto.SalesDirectlyReadDTO;
import com.lyf.scm.common.enums.ResponseMsg;
import com.lyf.scm.common.enums.SalesPlanDirectlyEnum;
import com.lyf.scm.common.enums.SalesPlanTypeEnum;
import com.rome.arch.core.exception.RomeException;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * description:
 *
 * @author: haodong
 * @data: 2020/11/11 18:04
 */
public class DirectlyDataListener extends AnalysisEventListener<SalesDirectlyReadDTO> {
    private static final int[] DATE_TITLE_INDEXS = new int[]{5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
    private static String DELIMITER = "/";
    private Map<Integer, Date> avDateRange;
    public List<SalesPlanDirectlyDTO> salesPlanDirectlyList = new ArrayList<>();

    @Override
    public void invoke(SalesDirectlyReadDTO data, AnalysisContext context) {
        if (avDateRange.size() == 0) {
            return;
        }
        if (!data.getGmvTarget().equals(SalesPlanDirectlyEnum.NOW_CONFIRM.getDesc())) {
            return;
        }
        setParamList(data, context);
    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    /**
     * 读取表头数据
     *
     * @param headMap
     * @param context
     * @return void
     **/
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        //解析日期范围，提取有效列数据
        Date date = new Date();
        Date startDate = DateUtil.beginOfWeek(date);
        String year = DateUtil.format(startDate, "yyyy.");
        Map<Integer, Date> map = new HashMap<>();
        Date previousDate = null;
        Date itemDate;
        for (int item : DATE_TITLE_INDEXS) {
            itemDate = DateUtil.parse(year + headMap.get(item).split("-")[0], "yyyy.MM.dd");
            if (previousDate == null) {
                previousDate = itemDate;
            }
            //如果当前时间小于前一个时间，将当前时间转换为下一年的时间
            if (itemDate.getTime() < previousDate.getTime()) {
                itemDate = DateUtil.offset(itemDate, DateField.YEAR, 1);
            }
            if (startDate.getTime() <= itemDate.getTime()) {
                map.put(item, itemDate);
            }
            previousDate = itemDate;
        }
        this.avDateRange = map;
    }

    /**
     * 解析文件数据
     *
     * @param data
     * @param context
     */
    private void setParamList(SalesDirectlyReadDTO data, AnalysisContext context) {
        String province = null;
        String city = null;
        String county = null;
        String store = null;
        if (StringUtils.isNotEmpty(data.getArea())) {
            String[] areaArr = data.getArea().split(DELIMITER);
            switch (areaArr.length) {
                case 1:
                    province = areaArr[0];
                    break;
                case 2:
                    city = areaArr[1];
                    break;
                case 3:
                    county = areaArr[2];
                    break;
                case 4:
                    store = areaArr[3];
                    break;
                default:
                    break;
            }
        } else {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行区域信息不能为空");
        }
        String sku;
        String skuStr = data.getSku();
        if (StringUtils.isNotEmpty(skuStr)) {
            String[] skuInfo = skuStr.split(DELIMITER);
            if (skuInfo.length < 2) {
                throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行sku编码不能为空");
            }
            sku = skuInfo[1];
        } else {
            throw new RomeException(ResponseMsg.EXCEPTION.getCode(), "第" + (context.readRowHolder().getRowIndex() + 1) + "行sku编码不能为空");
        }
        //日期
        Integer index;
        SalesPlanDirectlyDTO directly;
        for (Map.Entry<Integer, Date> item : avDateRange.entrySet()) {
            directly = new SalesPlanDirectlyDTO();
            directly.setProvinceName(province);
            directly.setCityName(city);
            directly.setCountyName(county);
            directly.setStoreCode(store);
            directly.setSkuCode(sku);
            directly.setPlanStartDate(DateUtil.formatDate(item.getValue()));
            directly.setTypeList(Collections.singletonList(SalesPlanTypeEnum.PLAN_SEVENTEEN.getType()));
            index = item.getKey();
            switch (index) {
                case 5:
                    directly.setConfirmQty((data.getWeek1() == null || "".equals(data.getWeek1()) || "-".equals(data.getWeek1())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek1()));
                    break;
                case 6:
                    directly.setConfirmQty((data.getWeek2() == null || "".equals(data.getWeek2()) || "-".equals(data.getWeek2())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek2()));
                    break;
                case 7:
                    directly.setConfirmQty((data.getWeek3() == null || "".equals(data.getWeek3()) || "-".equals(data.getWeek3())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek3()));
                    break;
                case 8:
                    directly.setConfirmQty((data.getWeek4() == null || "".equals(data.getWeek4()) || "-".equals(data.getWeek4())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek4()));
                    break;
                case 9:
                    directly.setConfirmQty((data.getWeek5() == null || "".equals(data.getWeek5()) || "-".equals(data.getWeek5())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek5()));
                    break;
                case 10:
                    directly.setConfirmQty((data.getWeek6() == null || "".equals(data.getWeek6()) || "-".equals(data.getWeek6())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek6()));
                    break;
                case 11:
                    directly.setConfirmQty((data.getWeek7() == null || "".equals(data.getWeek7()) || "-".equals(data.getWeek7())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek7()));
                    break;
                case 12:
                    directly.setConfirmQty((data.getWeek8() == null || "".equals(data.getWeek8()) || "-".equals(data.getWeek8())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek8()));
                    break;
                case 13:
                    directly.setConfirmQty((data.getWeek9() == null || "".equals(data.getWeek9()) || "-".equals(data.getWeek9())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek9()));
                    break;
                case 14:
                    directly.setConfirmQty((data.getWeek10() == null || "".equals(data.getWeek10()) || "-".equals(data.getWeek10())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek10()));
                    break;
                case 15:
                    directly.setConfirmQty((data.getWeek11() == null || "".equals(data.getWeek11()) || "-".equals(data.getWeek11())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek11()));
                    break;
                case 16:
                    directly.setConfirmQty((data.getWeek12() == null || "".equals(data.getWeek12()) || "-".equals(data.getWeek12())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek12()));
                    break;
                case 17:
                    directly.setConfirmQty((data.getWeek13() == null || "".equals(data.getWeek13()) || "-".equals(data.getWeek13())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek13()));
                    break;
                case 18:
                    directly.setConfirmQty((data.getWeek14() == null || "".equals(data.getWeek14()) || "-".equals(data.getWeek14())) ? BigDecimal.ZERO : new BigDecimal(data.getWeek14()));
                    break;
                default:
                    break;
            }
            salesPlanDirectlyList.add(directly);
        }
    }

    public List<SalesPlanDirectlyDTO> getParamDataList() {
        return salesPlanDirectlyList;
    }
}
